/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.pdx.cs.guavadata.condition;

import edu.pdx.cs.guavadata.domain.Domain;
import edu.pdx.cs.guavadata.subclass.ConditionType;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author VuTran
 */
public abstract class Condition {

    public static Condition newCondition(ConditionType ct, List<Object> args) throws ConditionException {

        switch (ct) {
            case BETWEEN:
                return new BETCond(args);
            case CONTAINS:
                return new ContainsCond(args);
            case EQ:
                return new EQCond(args);
            case GE:
                return new GECond(args);
            case GT:
                return new GTCond(args);
            case ISNOTNULL:
                return new NotNullCond(args);
            case ISNULL:
                return new NullCond(args);
            case LE:
                return new LECond(args);
            case LT:
                return new LTCond(args);
            case NEQ:
                return new NEQCond(args);
            default:
                return null;
        }
    }

    public static Condition newCondition(ConditionType ct) throws ConditionException {
        List<Object> args = new ArrayList<Object>();
        return newCondition(ct, args);
    }

    public static Condition newCondition(ConditionType ct, Object arg) throws ConditionException {
        List<Object> args = new ArrayList<Object>();
        args.add(arg);
        return newCondition(ct, args);
    }

    public static Condition newCondition(ConditionType ct, Object arg1, Object arg2) throws ConditionException {
        List<Object> args = new ArrayList<Object>();
        args.add(arg1);
        args.add(arg2);
        return newCondition(ct, args);
    }

    public static int numArgsForCond(ConditionType ct) {
        switch (ct) {
            case BETWEEN:
                return 2;
            case CONTAINS:
                return 1;
            case EQ:
                return 1;
            case GE:
                return 1;
            case GT:
                return 1;
            case ISNOTNULL:
                return 0;
            case ISNULL:
                return 0;
            case LE:
                return 1;
            case LT:
                return 1;
            case NEQ:
                return 1;
            default:
                return -1;
        }
    }

    public static boolean needsOrderedForCond(ConditionType ct) {
        switch (ct) {
            case BETWEEN:
                return true;
            case CONTAINS:
                return false;
            case EQ:
                return false;
            case GE:
                return true;
            case GT:
                return true;
            case ISNOTNULL:
                return false;
            case ISNULL:
                return false;
            case LE:
                return true;
            case LT:
                return true;
            case NEQ:
                return false;
            default:
                return false;
        }
    }

    public static boolean needsContainForCond(ConditionType ct) {
        switch (ct) {
            case BETWEEN:
                return false;
            case CONTAINS:
                return true;
            case EQ:
                return false;
            case GE:
                return false;
            case GT:
                return false;
            case ISNOTNULL:
                return false;
            case ISNULL:
                return false;
            case LE:
                return false;
            case LT:
                return false;
            case NEQ:
                return false;
            default:
                return false;
        }
    }

    public static DisplayCondition[] getConditionList() {
        List<DisplayCondition> dcl = new ArrayList<DisplayCondition>();
            dcl.add(new DisplayCondition(ConditionType.BETWEEN, "Between"));
            dcl.add(new DisplayCondition(ConditionType.CONTAINS, "Contains"));
            dcl.add(new DisplayCondition(ConditionType.EQ, "=="));
            dcl.add(new DisplayCondition(ConditionType.GE, ">="));
            dcl.add(new DisplayCondition(ConditionType.GT, ">"));
            dcl.add(new DisplayCondition(ConditionType.ISNOTNULL, "Is Not Null"));
            dcl.add(new DisplayCondition(ConditionType.ISNULL, "Is Null"));
            dcl.add(new DisplayCondition(ConditionType.LE, "<="));
            dcl.add(new DisplayCondition(ConditionType.LT, "<"));
            dcl.add(new DisplayCondition(ConditionType.NEQ, "<>"));
            return (DisplayCondition[]) dcl.toArray();
    }

    public abstract ConditionType getCondType();
    public abstract int getNumArgs();
    public abstract List<Object> getArgs();
    public abstract boolean getNeedsOrdered();
    public abstract boolean getNeedsContain();
    public abstract boolean Validate(Object obj, Domain d);


}
